package com.haredot.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.haredot.dto.FuncDto;
import com.haredot.entity.Func;
import com.haredot.entity.Menu;
import com.haredot.exception.ServiceAccessException;
import com.haredot.mapper.FuncMapper;
import com.haredot.service.FuncService;
import com.haredot.vo.FuncVo;
import com.haredot.vo.PageVo;
import com.haredot.vo.R;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
@Transactional(rollbackFor = Exception.class)
public class FuncServiceImpl implements FuncService {

    @Resource
    private FuncMapper funcMapper ;

    @Override
    @Cacheable(cacheNames = "func:all")
    public R<PageVo> queryFuncsByCondition(PageVo pageVo, Map<String, Object> params) {

        PageInfo<FuncDto> pageInfo = PageHelper.startPage(pageVo)
                .doSelectPageInfo(() -> funcMapper.findFuncsByCondtion(params));

        pageVo.setTotal(pageInfo.getTotal()).setList(pageInfo.getList());

        return R.<PageVo>ok().data(pageVo);
    }

    @Override
    public R<?> saveFunc(FuncVo funcVo) {
        // 根据功能名、查询功能是否已经存在
        Func func = funcMapper.findFuncByName(funcVo.getFuncName()) ;

        if (func != null) return R.fail(R.StatusCode.BAD).data(Map.of("funcName", "功能名已存在"));

        // 插入系统表
        int len = funcMapper.insert(funcVo);
        if (len != 1) throw new ServiceAccessException("插入功能失败、期待影响 1行、实际影响" + len + "行") ;

        // 继续 将功能和菜单进行绑定
        funcMapper.batchSaveMenusByFuncId(funcVo.getId(), funcVo.getMenus());

        return R.ok().build();
    }

    @Override
    public R<?> queryMenusRefFunc(Long funcId) {

        List<Menu> menus = funcMapper.findMenusRefFuncId(funcId) ;

        return R.<Menu>ok().data(menus);
    }

    @Override
    public R<?> batchDelete(List<Long> funcIds) {

        int len = funcMapper.batchRemoveByFuncId(funcIds);

        if (len != funcIds.size()) throw new ServiceAccessException("批量删除失败、期待删除" + funcIds.size() + "条记录、实际删除了" + len  + "条") ;

        return R.ok().build();
    }

    @Override
    public R<?> removeFunc(Long funcId) {

        int len = funcMapper.deleteById(funcId);

        if (len != 1) throw new ServiceAccessException("删除失败、期待删除 1 条记录、实际删除了" + len  + "条") ;

        return R.ok().build();
    }

    @Override
    public R<?> updateFunc(FuncVo funcVo) {
        // 根据功能名、查询功能是否已经存在
        Func func = funcMapper.findFuncByName(funcVo.getFuncName()) ;

        if (func != null && !Objects.equals(func.getId(), funcVo.getId())) {
            return R.fail(R.StatusCode.BAD).data(Map.of("funcName", "功能名已存在"));
        }

        // 插入系统表
        int len = funcMapper.update(funcVo);
        if (len != 1) throw new ServiceAccessException("修改功能失败、期待影响 1行、实际影响" + len + "行") ;

        // 继续 将功能和菜单进行绑定 (先解除绑定、再绑定)
        funcMapper.batchRemoveMenuAndFuncByFunc(funcVo.getId()) ;
        // 批量插入
        funcMapper.batchSaveMenusByFuncId(funcVo.getId(), funcVo.getMenus());

        return R.ok().build();
    }
}
